我正在和一些使用哈希引用的Perl搏斗.
最后,事实证明我的问题是这一行:
$myhash{$key} |= {};
也就是说,"给$ myhash {$ key}一个对空哈希的引用,除非它已经有一个值".
然而,解除引用并尝试将其用作哈希引用会导致使用字符串作为哈希引用的解释器错误.
将其更改为:
if( ! exists $myhash{$key}) { $myhash{$key} = {}; }
......让事情奏效.
所以我没有问题.但我很好奇发生了什么事.
谁能解释一下?
Perl有速记赋值运算符.该||=
操作通常用于为由于有逻辑运算符返回最后计算值的Perl的功能变量设置默认值.问题是,你使用的|=
是一个按位或代替||=
这是一个合乎逻辑的或.
从Perl 5.10开始,最好使用它//=
.//
是逻辑定义的或运算符,并且在定义当前值但是为false的极端情况下不会失败.
您看到使用字符串作为哈希引用的错误的原因是因为您使用了错误的运算符.|=
表示"按位或分配".换一种说法,
$foo |= $bar;
是相同的
$foo = $foo | $bar
您的示例中发生的情况是您的新匿名哈希引用正在进行字符串化,然后按值进行按位或运算$myhash{$key}
.为了进一步混淆问题,如果$myhash{$key}
当时未定义,则值是哈希引用的简单字符串化,如下所示HASH(0x80fc284)
.因此,如果您粗略地检查结构,它可能看起来像一个哈希引用,但事实并非如此.这是一些有用的输出Data::Dumper
:
perl -MData::Dumper -le '$hash{foo} |= { }; print Dumper \%hash' $VAR1 = { 'foo' => 'HASH(0x80fc284)' };
以下是使用正确运算符时的结果:
perl -MData::Dumper -le '$hash{foo} ||= { }; print Dumper \%hash' $VAR1 = { 'foo' => {} };